--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
RNode_Firmware.ino linux-daemon (47514771) Text, 24.43 KB
T8b949e// MIT License
T8b949e//
T8b949e// Copyright (c) 2022 Mark Qvist - unsigned.io/rnode
T8b949e//
T8b949e// Permission is hereby granted, free of charge, to any person obtaining a copy
T8b949e// of this software and associated documentation files (the "Software"), to deal
T8b949e// in the Software without restriction, including without limitation the rights
T8b949e// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
T8b949e// copies of the Software, and to permit persons to whom the Software is
T8b949e// furnished to do so, subject to the following conditions:
T8b949e//
T8b949e// The above copyright notice and this permission notice shall be included in all
T8b949e// copies or substantial portions of the Software.
T8b949e//
T8b949e// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
T8b949e// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
T8b949e// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
T8b949e// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
T8b949e// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
T8b949e// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
T8b949e// SOFTWARE.
Tff7b72#Tff7b72include T8b949e"Platform.h"
Tff7b72#Tff7b72if LIBRARY_TYPE == LIBRARY_ARDUINO
Tff7b72#Tff7b72include T8b949e<Arduino.h>
Tff7b72#Tff7b72include T8b949e<SPI.h>
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72include T8b949e"Utilities.h"
Te6edf3FIFOBuffer Te6edf3serialFIFOTb4b4b4;
Tff7b72uint8_t Te6edf3serialBufferTb4b4b4[Te6edf3CONFIG_UART_BUFFER_SIZETff7b72+T79c0ff1Tb4b4b4]Tb4b4b4;
Te6edf3FIFOBuffer16 Te6edf3packet_startsTb4b4b4;
Tff7b72uint16_t Te6edf3packet_starts_bufTb4b4b4[Te6edf3CONFIG_QUEUE_MAX_LENGTHTff7b72+T79c0ff1Tb4b4b4]Tb4b4b4;
Te6edf3FIFOBuffer16 Te6edf3packet_lengthsTb4b4b4;
Tff7b72uint16_t Te6edf3packet_lengths_bufTb4b4b4[Te6edf3CONFIG_QUEUE_MAX_LENGTHTff7b72+T79c0ff1Tb4b4b4]Tb4b4b4;
Tff7b72uint8_t Te6edf3packet_queueTb4b4b4[Te6edf3CONFIG_QUEUE_SIZETb4b4b4]Tb4b4b4;
Tff7b72volatile Tff7b72uint8_t Te6edf3queue_height Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72volatile Tff7b72uint16_t Te6edf3queued_bytes Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72volatile Tff7b72uint16_t Te6edf3queue_cursor Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72volatile Tff7b72uint16_t Te6edf3current_packet_start Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72volatile Tff7b72bool Te6edf3serial_buffering Tff7b72= Tff7b72falseTb4b4b4;
Tff7b72char Te6edf3sbufTb4b4b4[T79c0ff128Tb4b4b4]Tb4b4b4;
Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Tff7b72bool Te6edf3packet_ready Tff7b72= Tff7b72falseTb4b4b4;
Tff7b72#Tff7b72endif
T8b949e// Arduino C doesn't need pre-declarations to call functions that appear later,
T8b949e// but standard C does.
Tff7b72void Td2a8ffserial_interrupt_initTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72void Td2a8ffvalidateStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72void Td2a8ffupdate_radio_lockTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72void Td2a8fftransmitTb4b4b4(Tff7b72uint16_t Td2a8ffsizeTb4b4b4)Tb4b4b4;
Tff7b72void Td2a8ffbuffer_serialTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72void Td2a8ffserial_pollTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72void Tffa657setupTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Td2a8ffdelayTb4b4b4(T79c0ff500Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3eeprom_openTb4b4b4(Te6edf3EEPROM_SIZETb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if LIBRARY_TYPE == LIBRARY_ARDUINO
T8b949e// Seed the PRNG
Td2a8ffrandomSeedTb4b4b4(Td2a8ffanalogReadTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
T8b949e// Initialise serial communication
Te6edf3memsetTb4b4b4(Te6edf3serialBufferTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3serialBufferTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3fifo_initTb4b4b4(Tff7b72&Te6edf3serialFIFOTb4b4b4, Te6edf3serialBufferTb4b4b4, Te6edf3CONFIG_UART_BUFFER_SIZETb4b4b4)Tb4b4b4;
Td2a8ffSerialTb4b4b4.Td2a8ffbeginTb4b4b4(Te6edf3serial_baudrateTb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Tff7b72!Td2a8ffSerialTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Td2a8ffSerialTb4b4b4.Te6edf3setRxBufferSizeTb4b4b4(Te6edf3CONFIG_UART_BUFFER_SIZETb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3serial_interrupt_initTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if LIBRARY_TYPE == LIBRARY_ARDUINO
T8b949e// Configure input and output pins
Td2a8ffpinModeTb4b4b4(Te6edf3pin_led_rxTb4b4b4, Tff7b72OUTPUTTb4b4b4)Tb4b4b4;
Td2a8ffpinModeTb4b4b4(Te6edf3pin_led_txTb4b4b4, Tff7b72OUTPUTTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
T8b949e// Initialise buffers
Te6edf3memsetTb4b4b4(Te6edf3pbufTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3pbufTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3memsetTb4b4b4(Te6edf3cbufTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3cbufTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3memsetTb4b4b4(Te6edf3packet_queueTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3packet_queueTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3memsetTb4b4b4(Te6edf3packet_starts_bufTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3packet_starts_bufTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3fifo16_initTb4b4b4(Tff7b72&Te6edf3packet_startsTb4b4b4, Te6edf3packet_starts_bufTb4b4b4, Te6edf3CONFIG_QUEUE_MAX_LENGTHTb4b4b4)Tb4b4b4;
Te6edf3memsetTb4b4b4(Te6edf3packet_lengths_bufTb4b4b4, T79c0ff0Tb4b4b4, Tff7b72sizeofTb4b4b4(Te6edf3packet_starts_bufTb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3fifo16_initTb4b4b4(Tff7b72&Te6edf3packet_lengthsTb4b4b4, Te6edf3packet_lengths_bufTb4b4b4, Te6edf3CONFIG_QUEUE_MAX_LENGTHTb4b4b4)Tb4b4b4;
T8b949e// Set chip select, reset and interrupt
T8b949e// pins for the LoRa module
Te6edf3LoRaTb4b4b4.Te6edf3setPinsTb4b4b4(Te6edf3pin_csTb4b4b4, Te6edf3pin_resetTb4b4b4, Te6edf3pin_dioTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Tff7b72#Tff7b72if BOARD_MODEL == BOARD_TBEAM
Td2a8ffWireTb4b4b4.Td2a8ffbeginTb4b4b4(Te6edf3I2C_SDATb4b4b4, Te6edf3I2C_SCLTb4b4b4)Tb4b4b4;
Te6edf3initPMUTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3kiss_indicate_resetTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
T8b949e// Validate board health, EEPROM and config
Te6edf3validateStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72void Td2a8fflora_receiveTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3implicitTb4b4b4) Tb4b4b4{
Te6edf3LoRaTb4b4b4.Te6edf3receiveTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3LoRaTb4b4b4.Te6edf3receiveTb4b4b4(Te6edf3implicit_lTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72inline Tff7b72void Td2a8ffkiss_write_packetTb4b4b4(Tb4b4b4) Tb4b4b4{
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3FENDTb4b4b4)Tb4b4b4;
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3CMD_DATATb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72uint16_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3read_lenTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72uint8_t Tff7b72byte Tff7b72= Te6edf3pbufTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72byte Tff7b72=Tff7b72= Te6edf3FENDTb4b4b4) Tb4b4b4{ Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3FESCTb4b4b4)Tb4b4b4; Tff7b72byte Tff7b72= Te6edf3TFENDTb4b4b4; Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72byte Tff7b72=Tff7b72= Te6edf3FESCTb4b4b4) Tb4b4b4{ Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3FESCTb4b4b4)Tb4b4b4; Tff7b72byte Tff7b72= Te6edf3TFESCTb4b4b4; Tb4b4b4}
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Tff7b72byteTb4b4b4)Tb4b4b4;
Tb4b4b4}
Td2a8ffSerialTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3FENDTb4b4b4)Tb4b4b4;
Te6edf3read_len Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Te6edf3packet_ready Tff7b72= Tff7b72falseTb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72inline Tff7b72void Td2a8ffgetPacketDataTb4b4b4(Tff7b72uint16_t Te6edf3lenTb4b4b4) Tb4b4b4{
Tff7b72while Tb4b4b4(Te6edf3lenTff7b72-Tff7b72- Tff7b72&Tff7b72& Te6edf3read_len Tff7b72< Te6edf3MTUTb4b4b4) Tb4b4b4{
Te6edf3pbufTb4b4b4[Te6edf3read_lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3LoRaTb4b4b4.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72void Te6edf3ISR_VECT Td2a8ffreceive_callbackTb4b4b4(Tff7b72int Te6edf3packet_sizeTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if LIBRARY_TYPE == LIBRARY_C
Te6edf3stdTff7b72:Tff7b72:Te6edf3cerr Tff7b72<Tff7b72< Ta5d6ff"Ta5d6ffGot packet of Ta5d6ff" Tff7b72<Tff7b72< Te6edf3packet_size Tff7b72<Tff7b72< Ta5d6ff"Ta5d6ff bytesTa5d6ff" Tff7b72<Tff7b72< Te6edf3stdTff7b72:Tff7b72:Te6edf3endlTb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3promiscTb4b4b4) Tb4b4b4{
T8b949e// The standard operating mode allows large
T8b949e// packets with a payload up to 500 bytes,
T8b949e// by combining two raw LoRa packets.
T8b949e// We read the 1-byte header and extract
T8b949e// packet sequence number and split flags
Tff7b72uint8_t Te6edf3header Tff7b72= Te6edf3LoRaTb4b4b4.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3packet_sizeTff7b72-Tff7b72-Tb4b4b4;
Tff7b72uint8_t Te6edf3sequence Tff7b72= Te6edf3packetSequenceTb4b4b4(Te6edf3headerTb4b4b4)Tb4b4b4;
Tff7b72bool Td2a8ffready Tff7b72= Tff7b72falseTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3isSplitPacketTb4b4b4(Te6edf3headerTb4b4b4) Tff7b72&Tff7b72& Te6edf3seq Tff7b72=Tff7b72= Te6edf3SEQ_UNSETTb4b4b4) Tb4b4b4{
T8b949e// This is the first part of a split
T8b949e// packet, so we set the seq variable
T8b949e// and add the data to the buffer
Tff7b72#Tff7b72if LIBRARY_TYPE == LIBRARY_C
Te6edf3stdTff7b72:Tff7b72:Te6edf3cerr Tff7b72<Tff7b72< Ta5d6ff"Tffea00\tTa5d6ffIs first part of split packetTa5d6ff" Tff7b72<Tff7b72< Te6edf3stdTff7b72:Tff7b72:Te6edf3endlTb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3read_len Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3seq Tff7b72= Te6edf3sequenceTb4b4b4;
Tff7b72#Tff7b72if MCU_VARIANT != MCU_ESP32
Te6edf3last_rssi Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetRssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3last_snr_raw Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetSnrRawTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3getPacketDataTb4b4b4(Te6edf3packet_sizeTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3isSplitPacketTb4b4b4(Te6edf3headerTb4b4b4) Tff7b72&Tff7b72& Te6edf3seq Tff7b72=Tff7b72= Te6edf3sequenceTb4b4b4) Tb4b4b4{
T8b949e// This is the second part of a split
T8b949e// packet, so we add it to the buffer
T8b949e// and set the ready flag.
Tff7b72#Tff7b72if LIBRARY_TYPE == LIBRARY_C
Te6edf3stdTff7b72:Tff7b72:Te6edf3cerr Tff7b72<Tff7b72< Ta5d6ff"Tffea00\tTa5d6ffIs second part of split packetTa5d6ff" Tff7b72<Tff7b72< Te6edf3stdTff7b72:Tff7b72:Te6edf3endlTb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if MCU_VARIANT != MCU_ESP32
Te6edf3last_rssi Tff7b72= Tb4b4b4(Te6edf3last_rssiTff7b72+Te6edf3LoRaTb4b4b4.Te6edf3packetRssiTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72/T79c0ff2Tb4b4b4;
Te6edf3last_snr_raw Tff7b72= Tb4b4b4(Te6edf3last_snr_rawTff7b72+Te6edf3LoRaTb4b4b4.Te6edf3packetSnrRawTb4b4b4(Tb4b4b4)Tb4b4b4)Tff7b72/T79c0ff2Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3getPacketDataTb4b4b4(Te6edf3packet_sizeTb4b4b4)Tb4b4b4;
Te6edf3seq Tff7b72= Te6edf3SEQ_UNSETTb4b4b4;
Td2a8ffready Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3isSplitPacketTb4b4b4(Te6edf3headerTb4b4b4) Tff7b72&Tff7b72& Te6edf3seq Tff7b72!Tff7b72= Te6edf3sequenceTb4b4b4) Tb4b4b4{
T8b949e// This split packet does not carry the
T8b949e// same sequence id, so we must assume
T8b949e// that we are seeing the first part of
T8b949e// a new split packet.
Tff7b72#Tff7b72if LIBRARY_TYPE == LIBRARY_C
Te6edf3stdTff7b72:Tff7b72:Te6edf3cerr Tff7b72<Tff7b72< Ta5d6ff"Tffea00\tTa5d6ffIs first part of a different split packetTa5d6ff" Tff7b72<Tff7b72< Te6edf3stdTff7b72:Tff7b72:Te6edf3endlTb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3read_len Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3seq Tff7b72= Te6edf3sequenceTb4b4b4;
Tff7b72#Tff7b72if MCU_VARIANT != MCU_ESP32
Te6edf3last_rssi Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetRssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3last_snr_raw Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetSnrRawTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3getPacketDataTb4b4b4(Te6edf3packet_sizeTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Tff7b72!Te6edf3isSplitPacketTb4b4b4(Te6edf3headerTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// This is not a split packet, so we
T8b949e// just read it and set the ready
T8b949e// flag to true.
Tff7b72#Tff7b72if LIBRARY_TYPE == LIBRARY_C
Te6edf3stdTff7b72:Tff7b72:Te6edf3cerr Tff7b72<Tff7b72< Ta5d6ff"Tffea00\tTa5d6ffIs complete packetTa5d6ff" Tff7b72<Tff7b72< Te6edf3stdTff7b72:Tff7b72:Te6edf3endlTb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3seq Tff7b72!Tff7b72= Te6edf3SEQ_UNSETTb4b4b4) Tb4b4b4{
T8b949e// If we already had part of a split
T8b949e// packet in the buffer, we clear it.
Te6edf3read_len Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3seq Tff7b72= Te6edf3SEQ_UNSETTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72if MCU_VARIANT != MCU_ESP32
Te6edf3last_rssi Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetRssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3last_snr_raw Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetSnrRawTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3getPacketDataTb4b4b4(Te6edf3packet_sizeTb4b4b4)Tb4b4b4;
Td2a8ffready Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Td2a8ffreadyTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if MCU_VARIANT != MCU_ESP32
T8b949e// We first signal the RSSI of the
T8b949e// recieved packet to the host.
Te6edf3kiss_indicate_stat_rssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_stat_snrTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// And then write the entire packet
Te6edf3kiss_write_packetTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3packet_ready Tff7b72= Tff7b72trueTb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// In promiscuous mode, raw packets are
T8b949e// output directly to the host
Te6edf3read_len Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72#Tff7b72if MCU_VARIANT != MCU_ESP32
Te6edf3last_rssi Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetRssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3last_snr_raw Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetSnrRawTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3getPacketDataTb4b4b4(Te6edf3packet_sizeTb4b4b4)Tb4b4b4;
T8b949e// We first signal the RSSI of the
T8b949e// recieved packet to the host.
Te6edf3kiss_indicate_stat_rssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_stat_snrTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// And then write the entire packet
Te6edf3kiss_write_packetTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Te6edf3getPacketDataTb4b4b4(Te6edf3packet_sizeTb4b4b4)Tb4b4b4;
Te6edf3packet_ready Tff7b72= Tff7b72trueTb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tb4b4b4}
Tff7b72bool Td2a8ffstartRadioTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3update_radio_lockTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3radio_onlineTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3radio_locked Tff7b72&Tff7b72& Te6edf3hw_readyTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3LoRaTb4b4b4.Td2a8ffbeginTb4b4b4(Te6edf3lora_freqTb4b4b4)Tb4b4b4) Tb4b4b4{
T8b949e// The radio could not be started.
T8b949e// Indicate this failure over both the
T8b949e// serial port and with the onboard LEDs
Te6edf3kiss_indicate_errorTb4b4b4(Te6edf3ERROR_INITRADIOTb4b4b4)Tb4b4b4;
Te6edf3led_indicate_errorTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4;
Tff7b72return Tff7b72falseTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3radio_online Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3setTXPowerTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3setBandwidthTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3setSpreadingFactorTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3setCodingRateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3getFrequencyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3LoRaTb4b4b4.Te6edf3enableCrcTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3LoRaTb4b4b4.Td2a8ffonReceiveTb4b4b4(Te6edf3receive_callbackTb4b4b4)Tb4b4b4;
Te6edf3lora_receiveTb4b4b4(Tb4b4b4)Tb4b4b4;
T8b949e// Flash an info pattern to indicate
T8b949e// that the radio is now on
Te6edf3kiss_indicate_radiostateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3led_indicate_infoTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4;
Tff7b72return Tff7b72trueTb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// Flash a warning pattern to indicate
T8b949e// that the radio was locked, and thus
T8b949e// not started
Te6edf3radio_online Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3kiss_indicate_radiostateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3led_indicate_warningTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4;
Tff7b72return Tff7b72falseTb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// If radio is already on, we silently
T8b949e// ignore the request.
Te6edf3kiss_indicate_radiostateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72return Tff7b72trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72void Td2a8ffstopRadioTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3LoRaTb4b4b4.Td2a8ffendTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3radio_online Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Tff7b72void Td2a8ffupdate_radio_lockTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3lora_freq Tff7b72!Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3lora_bw Tff7b72!Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3lora_txp Tff7b72!Tff7b72= T79c0ff0xFF Tff7b72&Tff7b72& Te6edf3lora_sf Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3radio_locked Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3radio_locked Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72bool Td2a8ffqueueFullTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Tb4b4b4(Te6edf3queue_height Tff7b72>Tff7b72= Te6edf3CONFIG_QUEUE_MAX_LENGTH Tff7b72|Tff7b72| Te6edf3queued_bytes Tff7b72>Tff7b72= Te6edf3CONFIG_QUEUE_SIZETb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72volatile Tff7b72bool Te6edf3queue_flushing Tff7b72= Tff7b72falseTb4b4b4;
Tff7b72void Td2a8ffflushQueueTb4b4b4(Tff7b72voidTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3queue_flushingTb4b4b4) Tb4b4b4{
Te6edf3queue_flushing Tff7b72= Tff7b72trueTb4b4b4;
Tff7b72uint16_t Te6edf3processed Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72#Tff7b72if SERIAL_EVENTS == SERIAL_POLLING
Tff7b72while Tb4b4b4(Tff7b72!Te6edf3fifo16_isemptyTb4b4b4(Tff7b72&Te6edf3packet_startsTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72else
Tff7b72while Tb4b4b4(Tff7b72!Te6edf3fifo16_isempty_lockedTb4b4b4(Tff7b72&Te6edf3packet_startsTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Tff7b72uint16_t Te6edf3start Tff7b72= Te6edf3fifo16_popTb4b4b4(Tff7b72&Te6edf3packet_startsTb4b4b4)Tb4b4b4;
Tff7b72uint16_t Te6edf3length Tff7b72= Te6edf3fifo16_popTb4b4b4(Tff7b72&Te6edf3packet_lengthsTb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3length Tff7b72>Tff7b72= Te6edf3MIN_L Tff7b72&Tff7b72& Te6edf3length Tff7b72<Tff7b72= Te6edf3MTUTb4b4b4) Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72uint16_t Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3lengthTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Tff7b72uint16_t Te6edf3pos Tff7b72= Tb4b4b4(Te6edf3startTff7b72+Te6edf3iTb4b4b4)Tff7b72%Te6edf3CONFIG_QUEUE_SIZETb4b4b4;
Te6edf3tbufTb4b4b4[Te6edf3iTb4b4b4] Tff7b72= Te6edf3packet_queueTb4b4b4[Te6edf3posTb4b4b4]Tb4b4b4;
Tb4b4b4}
Te6edf3transmitTb4b4b4(Te6edf3lengthTb4b4b4)Tb4b4b4;
Te6edf3processedTff7b72+Tff7b72+Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3queue_height Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3queued_bytes Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3queue_flushing Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Tff7b72void Te6edf3transmitTb4b4b4(Tff7b72uint16_t Td2a8ffsizeTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3radio_onlineTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3promiscTb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if LIBRARY_TYPE == LIBRARY_C
Te6edf3stdTff7b72:Tff7b72:Te6edf3cerr Tff7b72<Tff7b72< Ta5d6ff"Ta5d6ffSending RNode packet(s) of Ta5d6ff" Tff7b72<Tff7b72< Td2a8ffsize Tff7b72<Tff7b72< Ta5d6ff"Ta5d6ff bytesTa5d6ff" Tff7b72<Tff7b72< Te6edf3stdTff7b72:Tff7b72:Te6edf3endlTb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3led_tx_onTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72uint16_t Te6edf3written Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72uint8_t Te6edf3header Tff7b72= Td2a8ffrandomTb4b4b4(T79c0ff256Tb4b4b4) Tff7b72& T79c0ff0xF0Tb4b4b4;
Tff7b72if Tb4b4b4(Td2a8ffsize Tff7b72> Te6edf3SINGLE_MTU Tff7b72- Te6edf3HEADER_LTb4b4b4) Tb4b4b4{
Te6edf3header Tff7b72= Te6edf3header Tff7b72| Te6edf3FLAG_SPLITTb4b4b4;
Tb4b4b4}
Te6edf3LoRaTb4b4b4.Td2a8ffbeginPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3LoRaTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3headerTb4b4b4)Tb4b4b4; Te6edf3writtenTff7b72+Tff7b72+Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72uint16_t Te6edf3iTff7b72=T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Td2a8ffsizeTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3LoRaTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3tbufTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3writtenTff7b72+Tff7b72+Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3written Tff7b72=Tff7b72= T79c0ff255Tb4b4b4) Tb4b4b4{
Te6edf3LoRaTb4b4b4.Td2a8ffendPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3LoRaTb4b4b4.Td2a8ffbeginPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3LoRaTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3headerTb4b4b4)Tb4b4b4;
Te6edf3written Tff7b72= T79c0ff1Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Te6edf3LoRaTb4b4b4.Td2a8ffendPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3led_tx_offTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3lora_receiveTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// In promiscuous mode, we only send out
T8b949e// plain raw LoRa packets with a maximum
T8b949e// payload of 255 bytes
Tff7b72#Tff7b72if LIBRARY_TYPE == LIBRARY_C
Te6edf3stdTff7b72:Tff7b72:Te6edf3cerr Tff7b72<Tff7b72< Ta5d6ff"Ta5d6ffSending standard packet of Ta5d6ff" Tff7b72<Tff7b72< Td2a8ffsize Tff7b72<Tff7b72< Ta5d6ff"Ta5d6ff bytesTa5d6ff" Tff7b72<Tff7b72< Te6edf3stdTff7b72:Tff7b72:Te6edf3endlTb4b4b4;
Tff7b72#Tff7b72endif
Te6edf3led_tx_onTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72uint16_t Te6edf3written Tff7b72= T79c0ff0Tb4b4b4;
T8b949e// Cap packets at 255 bytes
Tff7b72if Tb4b4b4(Td2a8ffsize Tff7b72> Te6edf3SINGLE_MTUTb4b4b4) Tb4b4b4{
Td2a8ffsize Tff7b72= Te6edf3SINGLE_MTUTb4b4b4;
Tb4b4b4}
T8b949e// If implicit header mode has been set,
T8b949e// set packet length to payload data length
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3implicitTb4b4b4) Tb4b4b4{
Te6edf3LoRaTb4b4b4.Td2a8ffbeginPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3LoRaTb4b4b4.Td2a8ffbeginPacketTb4b4b4(Td2a8ffsizeTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72for Tb4b4b4(Tff7b72uint16_t Te6edf3iTff7b72=T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Td2a8ffsizeTb4b4b4; Te6edf3iTff7b72+Tff7b72+Tb4b4b4) Tb4b4b4{
Te6edf3LoRaTb4b4b4.Td2a8ffwriteTb4b4b4(Te6edf3tbufTb4b4b4[Te6edf3iTb4b4b4]Tb4b4b4)Tb4b4b4;
Te6edf3writtenTff7b72+Tff7b72+Tb4b4b4;
Tb4b4b4}
Te6edf3LoRaTb4b4b4.Td2a8ffendPacketTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3led_tx_offTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3lora_receiveTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3kiss_indicate_errorTb4b4b4(Te6edf3ERROR_TXFAILEDTb4b4b4)Tb4b4b4;
Te6edf3led_indicate_errorTb4b4b4(T79c0ff5Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72void Te6edf3serialCallbackTb4b4b4(Tff7b72uint8_t Te6edf3sbyteTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3IN_FRAME Tff7b72&Tff7b72& Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FEND Tff7b72&Tff7b72& Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_DATATb4b4b4) Tb4b4b4{
Te6edf3IN_FRAME Tff7b72= Tff7b72falseTb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3fifo16_isfullTb4b4b4(Tff7b72&Te6edf3packet_startsTb4b4b4) Tff7b72&Tff7b72& Te6edf3queued_bytes Tff7b72< Te6edf3CONFIG_QUEUE_SIZETb4b4b4) Tb4b4b4{
Tff7b72uint16_t Te6edf3s Tff7b72= Te6edf3current_packet_startTb4b4b4;
Tff7b72int16_t Te6edf3e Tff7b72= Te6edf3queue_cursorT79c0ff-1Tb4b4b4; Tff7b72if Tb4b4b4(Te6edf3e Tff7b72=Tff7b72= T79c0ff-1Tb4b4b4) Te6edf3e Tff7b72= Te6edf3CONFIG_QUEUE_SIZET79c0ff-1Tb4b4b4;
Tff7b72uint16_t Te6edf3lTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3s Tff7b72!Tff7b72= Te6edf3eTb4b4b4) Tb4b4b4{
Te6edf3l Tff7b72= Tb4b4b4(Te6edf3s Tff7b72< Te6edf3eTb4b4b4) Tff7b72? Te6edf3e Tff7b72- Te6edf3s Tff7b72+ T79c0ff1 Tff7b72: Te6edf3CONFIG_QUEUE_SIZE Tff7b72- Te6edf3s Tff7b72+ Te6edf3e Tff7b72+ T79c0ff1Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3l Tff7b72= T79c0ff1Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3l Tff7b72>Tff7b72= Te6edf3MIN_LTb4b4b4) Tb4b4b4{
Te6edf3queue_heightTff7b72+Tff7b72+Tb4b4b4;
Te6edf3fifo16_pushTb4b4b4(Tff7b72&Te6edf3packet_startsTb4b4b4, Te6edf3sTb4b4b4)Tb4b4b4;
Te6edf3fifo16_pushTb4b4b4(Tff7b72&Te6edf3packet_lengthsTb4b4b4, Te6edf3lTb4b4b4)Tb4b4b4;
Te6edf3current_packet_start Tff7b72= Te6edf3queue_cursorTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FENDTb4b4b4) Tb4b4b4{
Te6edf3IN_FRAME Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3command Tff7b72= Te6edf3CMD_UNKNOWNTb4b4b4;
Te6edf3frame_len Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3IN_FRAME Tff7b72&Tff7b72& Te6edf3frame_len Tff7b72< Te6edf3MTUTb4b4b4) Tb4b4b4{
T8b949e// Have a look at the command byte first
Tff7b72if Tb4b4b4(Te6edf3frame_len Tff7b72=Tff7b72= T79c0ff0 Tff7b72&Tff7b72& Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_UNKNOWNTb4b4b4) Tb4b4b4{
Te6edf3command Tff7b72= Te6edf3sbyteTb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_DATATb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FESCTb4b4b4) Tb4b4b4{
Te6edf3ESCAPE Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3ESCAPETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFENDTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FENDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFESCTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FESCTb4b4b4;
Te6edf3ESCAPE Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3queue_height Tff7b72< Te6edf3CONFIG_QUEUE_MAX_LENGTH Tff7b72&Tff7b72& Te6edf3queued_bytes Tff7b72< Te6edf3CONFIG_QUEUE_SIZETb4b4b4) Tb4b4b4{
Te6edf3queued_bytesTff7b72+Tff7b72+Tb4b4b4;
Te6edf3packet_queueTb4b4b4[Te6edf3queue_cursorTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3sbyteTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3queue_cursor Tff7b72=Tff7b72= Te6edf3CONFIG_QUEUE_SIZETb4b4b4) Te6edf3queue_cursor Tff7b72= T79c0ff0Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_FREQUENCYTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FESCTb4b4b4) Tb4b4b4{
Te6edf3ESCAPE Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3ESCAPETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFENDTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FENDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFESCTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FESCTb4b4b4;
Te6edf3ESCAPE Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Te6edf3cbufTb4b4b4[Te6edf3frame_lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3sbyteTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3frame_len Tff7b72=Tff7b72= T79c0ff4Tb4b4b4) Tb4b4b4{
Tff7b72uint32_t Te6edf3freq Tff7b72= Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff24 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72<Tff7b72< T79c0ff16 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3freq Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_frequencyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3lora_freq Tff7b72= Te6edf3freqTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3op_mode Tff7b72=Tff7b72= Te6edf3MODE_HOSTTb4b4b4) Te6edf3setFrequencyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_frequencyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_BANDWIDTHTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FESCTb4b4b4) Tb4b4b4{
Te6edf3ESCAPE Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3ESCAPETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFENDTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FENDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFESCTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FESCTb4b4b4;
Te6edf3ESCAPE Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Te6edf3cbufTb4b4b4[Te6edf3frame_lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3sbyteTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3frame_len Tff7b72=Tff7b72= T79c0ff4Tb4b4b4) Tb4b4b4{
Tff7b72uint32_t Te6edf3bw Tff7b72= Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72<Tff7b72< T79c0ff24 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff1Tb4b4b4] Tff7b72<Tff7b72< T79c0ff16 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff2Tb4b4b4] Tff7b72<Tff7b72< T79c0ff8 Tff7b72| Tb4b4b4(Tff7b72uint32_tTb4b4b4)Te6edf3cbufTb4b4b4[T79c0ff3Tb4b4b4]Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3bw Tff7b72=Tff7b72= T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_bandwidthTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3lora_bw Tff7b72= Te6edf3bwTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3op_mode Tff7b72=Tff7b72= Te6edf3MODE_HOSTTb4b4b4) Te6edf3setBandwidthTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_bandwidthTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_TXPOWERTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_txpowerTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72int Te6edf3txp Tff7b72= Te6edf3sbyteTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3txp Tff7b72> T79c0ff17Tb4b4b4) Te6edf3txp Tff7b72= T79c0ff17Tb4b4b4;
Te6edf3lora_txp Tff7b72= Te6edf3txpTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3op_mode Tff7b72=Tff7b72= Te6edf3MODE_HOSTTb4b4b4) Te6edf3setTXPowerTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_txpowerTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_SFTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_spreadingfactorTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72int Te6edf3sf Tff7b72= Te6edf3sbyteTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sf Tff7b72< T79c0ff6Tb4b4b4) Te6edf3sf Tff7b72= T79c0ff6Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sf Tff7b72> T79c0ff12Tb4b4b4) Te6edf3sf Tff7b72= T79c0ff12Tb4b4b4;
Te6edf3lora_sf Tff7b72= Te6edf3sfTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3op_mode Tff7b72=Tff7b72= Te6edf3MODE_HOSTTb4b4b4) Te6edf3setSpreadingFactorTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_spreadingfactorTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_CRTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_codingrateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72int Te6edf3cr Tff7b72= Te6edf3sbyteTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cr Tff7b72< T79c0ff5Tb4b4b4) Te6edf3cr Tff7b72= T79c0ff5Tb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3cr Tff7b72> T79c0ff8Tb4b4b4) Te6edf3cr Tff7b72= T79c0ff8Tb4b4b4;
Te6edf3lora_cr Tff7b72= Te6edf3crTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3op_mode Tff7b72=Tff7b72= Te6edf3MODE_HOSTTb4b4b4) Te6edf3setCodingRateTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_codingrateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_IMPLICITTb4b4b4) Tb4b4b4{
Te6edf3set_implicit_lengthTb4b4b4(Te6edf3sbyteTb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_implicit_lengthTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_RADIO_STATETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0xFFTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_radiostateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0x00Tb4b4b4) Tb4b4b4{
Te6edf3stopRadioTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_radiostateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0x01Tb4b4b4) Tb4b4b4{
Te6edf3startRadioTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_radiostateTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_STAT_RXTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_stat_rxTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_STAT_TXTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_stat_txTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_STAT_RSSITb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_stat_rssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_RADIO_LOCKTb4b4b4) Tb4b4b4{
Te6edf3update_radio_lockTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_radio_lockTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_BLINKTb4b4b4) Tb4b4b4{
Te6edf3led_indicate_infoTb4b4b4(Te6edf3sbyteTb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_RANDOMTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_randomTb4b4b4(Te6edf3getRandomTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_DETECTTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3DETECT_REQTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_detectTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_PROMISCTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0x01Tb4b4b4) Tb4b4b4{
Te6edf3promisc_enableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= T79c0ff0x00Tb4b4b4) Tb4b4b4{
Te6edf3promisc_disableTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3kiss_indicate_promiscTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_READYTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3queueFullTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_readyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3kiss_indicate_not_readyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_UNLOCK_ROMTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3ROM_UNLOCK_BYTETb4b4b4) Tb4b4b4{
Te6edf3unlock_romTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_RESETTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3CMD_RESET_BYTETb4b4b4) Tb4b4b4{
Te6edf3hard_resetTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_ROM_READTb4b4b4) Tb4b4b4{
Te6edf3kiss_dump_eepromTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_ROM_WRITETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3FESCTb4b4b4) Tb4b4b4{
Te6edf3ESCAPE Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3ESCAPETb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFENDTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FENDTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3sbyte Tff7b72=Tff7b72= Te6edf3TFESCTb4b4b4) Te6edf3sbyte Tff7b72= Te6edf3FESCTb4b4b4;
Te6edf3ESCAPE Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Te6edf3cbufTb4b4b4[Te6edf3frame_lenTff7b72+Tff7b72+Tb4b4b4] Tff7b72= Te6edf3sbyteTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3frame_len Tff7b72=Tff7b72= T79c0ff2Tb4b4b4) Tb4b4b4{
Te6edf3eeprom_writeTb4b4b4(Te6edf3cbufTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Te6edf3cbufTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_FW_VERSIONTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_versionTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_PLATFORMTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_platformTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_MCUTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_mcuTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_BOARDTb4b4b4) Tb4b4b4{
Te6edf3kiss_indicate_boardTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_CONF_SAVETb4b4b4) Tb4b4b4{
Te6edf3eeprom_conf_saveTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3command Tff7b72=Tff7b72= Te6edf3CMD_CONF_DELETETb4b4b4) Tb4b4b4{
Te6edf3eeprom_conf_deleteTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Te6edf3portMUX_TYPE Te6edf3update_lock Tff7b72= Te6edf3portMUX_INITIALIZER_UNLOCKEDTb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72void Te6edf3updateModemStatusTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Te6edf3portENTER_CRITICALTb4b4b4(Tff7b72&Te6edf3update_lockTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72uint8_t Te6edf3status Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3modemStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3last_status_update Tff7b72= Td2a8ffmillisTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Te6edf3portEXIT_CRITICALTb4b4b4(Tff7b72&Te6edf3update_lockTb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3status Tff7b72& Te6edf3SIG_DETECT Tff7b72=Tff7b72= Te6edf3SIG_DETECTTb4b4b4) Tb4b4b4{ Te6edf3stat_signal_detected Tff7b72= Tff7b72trueTb4b4b4; Tb4b4b4} Tff7b72else Tb4b4b4{ Te6edf3stat_signal_detected Tff7b72= Tff7b72falseTb4b4b4; Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3status Tff7b72& Te6edf3SIG_SYNCED Tff7b72=Tff7b72= Te6edf3SIG_SYNCEDTb4b4b4) Tb4b4b4{ Te6edf3stat_signal_synced Tff7b72= Tff7b72trueTb4b4b4; Tb4b4b4} Tff7b72else Tb4b4b4{ Te6edf3stat_signal_synced Tff7b72= Tff7b72falseTb4b4b4; Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3status Tff7b72& Te6edf3RX_ONGOING Tff7b72=Tff7b72= Te6edf3RX_ONGOINGTb4b4b4) Tb4b4b4{ Te6edf3stat_rx_ongoing Tff7b72= Tff7b72trueTb4b4b4; Tb4b4b4} Tff7b72else Tb4b4b4{ Te6edf3stat_rx_ongoing Tff7b72= Tff7b72falseTb4b4b4; Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3stat_signal_detected Tff7b72|Tff7b72| Te6edf3stat_signal_synced Tff7b72|Tff7b72| Te6edf3stat_rx_ongoingTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3dcd_count Tff7b72< Te6edf3dcd_thresholdTb4b4b4) Tb4b4b4{
Te6edf3dcd_countTff7b72+Tff7b72+Tb4b4b4;
Te6edf3dcd Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3dcd Tff7b72= Tff7b72trueTb4b4b4;
Te6edf3dcd_led Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3dcd_count Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3dcd_countTff7b72-Tff7b72-Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3dcd_led Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Te6edf3dcd Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3dcd_ledTb4b4b4) Tb4b4b4{
Te6edf3led_rx_onTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3led_rx_offTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72void Te6edf3checkModemStatusTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Td2a8ffmillisTb4b4b4(Tb4b4b4)Tff7b72-Te6edf3last_status_update Tff7b72>Tff7b72= Te6edf3status_interval_msTb4b4b4) Tb4b4b4{
Te6edf3updateModemStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72void Te6edf3validateStatusTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if MCU_VARIANT == MCU_1284P
Tff7b72uint8_t Te6edf3boot_flags Tff7b72= Te6edf3OPTIBOOT_MCUSRTb4b4b4;
Tff7b72uint8_t Te6edf3F_POR Tff7b72= Te6edf3PORFTb4b4b4;
Tff7b72uint8_t Te6edf3F_BOR Tff7b72= Te6edf3BORFTb4b4b4;
Tff7b72uint8_t Te6edf3F_WDR Tff7b72= Te6edf3WDRFTb4b4b4;
Tff7b72#Tff7b72elif MCU_VARIANT == MCU_2560
Tff7b72uint8_t Te6edf3boot_flags Tff7b72= Te6edf3OPTIBOOT_MCUSRTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3boot_flags Tff7b72=Tff7b72= T79c0ff0x00Tb4b4b4) Te6edf3boot_flags Tff7b72= Te6edf3START_FROM_BROWNOUTTb4b4b4;
Tff7b72uint8_t Te6edf3F_POR Tff7b72= Te6edf3PORFTb4b4b4;
Tff7b72uint8_t Te6edf3F_BOR Tff7b72= Te6edf3BORFTb4b4b4;
Tff7b72uint8_t Te6edf3F_WDR Tff7b72= Te6edf3WDRFTb4b4b4;
Tff7b72#Tff7b72elif MCU_VARIANT == MCU_ESP32
T8b949e// TODO: Get ESP32 boot flags
Tff7b72uint8_t Te6edf3boot_flags Tff7b72= Te6edf3START_FROM_POWERONTb4b4b4;
Tff7b72uint8_t Te6edf3F_POR Tff7b72= T79c0ff0x00Tb4b4b4;
Tff7b72uint8_t Te6edf3F_BOR Tff7b72= T79c0ff0x00Tb4b4b4;
Tff7b72uint8_t Te6edf3F_WDR Tff7b72= T79c0ff0x01Tb4b4b4;
Tff7b72#Tff7b72elif MCU_VARIANT == MCU_LINUX
T8b949e// Linux build always works like a clean boot.
Tff7b72uint8_t Te6edf3boot_flags Tff7b72= Te6edf3START_FROM_POWERONTb4b4b4;
Tff7b72uint8_t Te6edf3F_POR Tff7b72= T79c0ff0x00Tb4b4b4;
Tff7b72uint8_t Te6edf3F_BOR Tff7b72= T79c0ff0x00Tb4b4b4;
Tff7b72uint8_t Te6edf3F_WDR Tff7b72= T79c0ff0x01Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3boot_flags Tff7b72& Tb4b4b4(T79c0ff1Tff7b72<Tff7b72<Te6edf3F_PORTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3boot_vector Tff7b72= Te6edf3START_FROM_POWERONTb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3boot_flags Tff7b72& Tb4b4b4(T79c0ff1Tff7b72<Tff7b72<Te6edf3F_BORTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3boot_vector Tff7b72= Te6edf3START_FROM_BROWNOUTTb4b4b4;
Tb4b4b4} Tff7b72else Tff7b72if Tb4b4b4(Te6edf3boot_flags Tff7b72& Tb4b4b4(T79c0ff1Tff7b72<Tff7b72<Te6edf3F_WDRTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3boot_vector Tff7b72= Te6edf3START_FROM_BOOTLOADERTb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3debugTb4b4b4(Ta5d6ff"Ta5d6ffError, indeterminate boot vectorTffea00\rTffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3led_indicate_boot_errorTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3boot_vector Tff7b72=Tff7b72= Te6edf3START_FROM_BOOTLOADER Tff7b72|Tff7b72| Te6edf3boot_vector Tff7b72=Tff7b72= Te6edf3START_FROM_POWERONTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3eeprom_info_lockedTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3eeprom_product_validTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3eeprom_model_validTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3eeprom_hwrev_validTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3eeprom_checksum_validTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3hw_ready Tff7b72= Tff7b72trueTb4b4b4;
Tff7b72if Tb4b4b4(Te6edf3eeprom_have_confTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3eeprom_conf_loadTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3op_mode Tff7b72= Te6edf3MODE_TNCTb4b4b4;
Te6edf3startRadioTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3hw_ready Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3debugTb4b4b4(Ta5d6ff"Ta5d6ffError, EEPROM checksum incorrectTffea00\rTffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3hw_ready Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3debugTb4b4b4(Ta5d6ff"Ta5d6ffError, EEPROM product, model, or revision not validTffea00\rTffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3hw_ready Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3debugTb4b4b4(Ta5d6ff"Ta5d6ffError, EEPROM info not lockedTffea00\rTffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3hw_ready Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3debugTb4b4b4(Ta5d6ff"Ta5d6ffError, incorrect boot vectorTffea00\rTffea00\nTa5d6ff"Tb4b4b4)Tb4b4b4;
Te6edf3led_indicate_boot_errorTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72void Tffa657loopTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3radio_onlineTb4b4b4) Tb4b4b4{
Te6edf3checkModemStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72if MCU_VARIANT == MCU_ESP32
Tff7b72if Tb4b4b4(Te6edf3packet_readyTb4b4b4) Tb4b4b4{
Te6edf3portENTER_CRITICALTb4b4b4(Tff7b72&Te6edf3update_lockTb4b4b4)Tb4b4b4;
Te6edf3last_rssi Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetRssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3last_snr_raw Tff7b72= Te6edf3LoRaTb4b4b4.Te6edf3packetSnrRawTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3portEXIT_CRITICALTb4b4b4(Tff7b72&Te6edf3update_lockTb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_stat_rssiTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_indicate_stat_snrTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3kiss_write_packetTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if MCU_VARIANT == MCU_LINUX
T8b949e// We don't have interrupts, so we need to poll ofr received packets.
T8b949e// TODO: Is this fast enough? Or do we need threads or something?
Te6edf3LoRaTb4b4b4.Te6edf3pollReceiveTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tff7b72if Tb4b4b4(Te6edf3queue_height Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3dcd_waitingTb4b4b4) Te6edf3updateModemStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3dcd Tff7b72&Tff7b72& Tff7b72!Te6edf3dcd_ledTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3dcd_waitingTb4b4b4) Td2a8ffdelayTb4b4b4(Te6edf3lora_rx_turnaround_msTb4b4b4)Tb4b4b4;
Te6edf3updateModemStatusTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3dcdTb4b4b4) Tb4b4b4{
Te6edf3dcd_waiting Tff7b72= Tff7b72falseTb4b4b4;
Te6edf3flushQueueTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3dcd_waiting Tff7b72= Tff7b72trueTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3hw_readyTb4b4b4) Tb4b4b4{
Te6edf3led_indicate_standbyTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3led_indicate_not_readyTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3stopRadioTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72if SERIAL_EVENTS == SERIAL_POLLING
Te6edf3buffer_serialTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3fifo_isemptyTb4b4b4(Tff7b72&Te6edf3serialFIFOTb4b4b4)Tb4b4b4) Te6edf3serial_pollTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3fifo_isempty_lockedTb4b4b4(Tff7b72&Te6edf3serialFIFOTb4b4b4)Tb4b4b4) Te6edf3serial_pollTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72volatile Tff7b72bool Te6edf3serial_polling Tff7b72= Tff7b72falseTb4b4b4;
Tff7b72void Te6edf3serial_pollTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3serial_polling Tff7b72= Tff7b72trueTb4b4b4;
Tff7b72#Tff7b72if SERIAL_EVENTS == SERIAL_INTERRUPT
Tff7b72while Tb4b4b4(Tff7b72!Te6edf3fifo_isempty_lockedTb4b4b4(Tff7b72&Te6edf3serialFIFOTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72else
Tff7b72while Tb4b4b4(Tff7b72!Te6edf3fifo_isemptyTb4b4b4(Tff7b72&Te6edf3serialFIFOTb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72endif
Tff7b72char Te6edf3sbyte Tff7b72= Te6edf3fifo_popTb4b4b4(Tff7b72&Te6edf3serialFIFOTb4b4b4)Tb4b4b4;
Te6edf3serialCallbackTb4b4b4(Te6edf3sbyteTb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3serial_polling Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72if MCU_VARIANT != MCU_ESP32
Tff7b72#Tff7b72define MAX_CYCLES 20
Tff7b72#Tff7b72else
Tff7b72#Tff7b72define MAX_CYCLES 10
Tff7b72#Tff7b72endif
Tff7b72void Te6edf3buffer_serialTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3serial_bufferingTb4b4b4) Tb4b4b4{
Te6edf3serial_buffering Tff7b72= Tff7b72trueTb4b4b4;
Tff7b72uint8_t Te6edf3c Tff7b72= T79c0ff0Tb4b4b4;
Tff7b72while Tb4b4b4(Te6edf3c Tff7b72< Te6edf3MAX_CYCLES Tff7b72&Tff7b72& Td2a8ffSerialTb4b4b4.Td2a8ffavailableTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3cTff7b72+Tff7b72+Tb4b4b4;
Tff7b72#Tff7b72if SERIAL_EVENTS == SERIAL_INTERRUPT
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3fifo_isfull_lockedTb4b4b4(Tff7b72&Te6edf3serialFIFOTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3fifo_push_lockedTb4b4b4(Tff7b72&Te6edf3serialFIFOTb4b4b4, Td2a8ffSerialTb4b4b4.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72else
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3fifo_isfullTb4b4b4(Tff7b72&Te6edf3serialFIFOTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3fifo_pushTb4b4b4(Tff7b72&Te6edf3serialFIFOTb4b4b4, Td2a8ffSerialTb4b4b4.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tb4b4b4}
Te6edf3serial_buffering Tff7b72= Tff7b72falseTb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72void Te6edf3serial_interrupt_initTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72#Tff7b72if MCU_VARIANT == MCU_1284P
Te6edf3TCCR3A Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3TCCR3B Tff7b72= Te6edf3_BVTb4b4b4(Te6edf3CS10Tb4b4b4) Tff7b72|
Te6edf3_BVTb4b4b4(Te6edf3WGM33Tb4b4b4)Tff7b72|
Te6edf3_BVTb4b4b4(Te6edf3WGM32Tb4b4b4)Tb4b4b4;
T8b949e// Buffer incoming frames every 1ms
Te6edf3ICR3 Tff7b72= T79c0ff16000Tb4b4b4;
Te6edf3TIMSK3 Tff7b72= Te6edf3_BVTb4b4b4(Te6edf3ICIE3Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72elif MCU_VARIANT == MCU_2560
T8b949e// TODO: This should probably be updated for
T8b949e// atmega2560 support. Might be source of
T8b949e// reported issues from snh.
Te6edf3TCCR3A Tff7b72= T79c0ff0Tb4b4b4;
Te6edf3TCCR3B Tff7b72= Te6edf3_BVTb4b4b4(Te6edf3CS10Tb4b4b4) Tff7b72|
Te6edf3_BVTb4b4b4(Te6edf3WGM33Tb4b4b4)Tff7b72|
Te6edf3_BVTb4b4b4(Te6edf3WGM32Tb4b4b4)Tb4b4b4;
T8b949e// Buffer incoming frames every 1ms
Te6edf3ICR3 Tff7b72= T79c0ff16000Tb4b4b4;
Te6edf3TIMSK3 Tff7b72= Te6edf3_BVTb4b4b4(Te6edf3ICIE3Tb4b4b4)Tb4b4b4;
Tff7b72#Tff7b72else
T8b949e// No interrupt-based polling on other MCUs.
Tff7b72#Tff7b72endif
Tb4b4b4}
Tff7b72#Tff7b72if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
Te6edf3ISRTb4b4b4(Te6edf3TIMER3_CAPT_vectTb4b4b4) Tb4b4b4{
Te6edf3buffer_serialTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72#Tff7b72endif
Tff7b72#Tff7b72if PLATFORM == PLATFORM_LINUX
Tff7b72int Te6edf3mainTb4b4b4(Tff7b72int Te6edf3argcTb4b4b4, Tff7b72charTff7b72*Tff7b72* Te6edf3argvTb4b4b4) Tb4b4b4{
Tffa657setupTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72while Tb4b4b4(Tff7b72trueTb4b4b4) Tb4b4b4{
Tffa657loopTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}
Tff7b72#Tff7b72endif
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────